package org.clevernote.foundations;

import java.util.logging.Logger;

import ui.cmdline.parser.ArgType;
import ui.cmdline.parser.CommandLineArguments;
import ui.cmdline.parser.Parser;
import ui.cmdline.parser.ParserException;
import ui.cmdline.parser.types.BooleanArgType;
import ui.cmdline.parser.types.StringArgType;

import com.evernote.edam.error.EDAMSystemException;
import com.evernote.edam.error.EDAMUserException;
import com.facebook.thrift.TException;

public class CmdParser {

	private boolean debug_;
	private Parser parser_;
	private String password_;
	private boolean quiet_;
	private String username_;
	private boolean verbose_;
	private Logger logger_ = Logger.getLogger(CmdParser.class.getName());

	public CmdParser(String _name) throws ParserException {
		setup(_name);
	}

	protected void addHiddenArgument(ArgType type) throws ParserException {
	
		if (parser_ == null)
			throw new IllegalStateException("parser was not set up yet");
		parser_.addHiddenArgument(type);
	
	}

	protected void addMandatoryArgument(ArgType type) throws ParserException {
	
		if (parser_ == null)
			throw new IllegalStateException("parser was not set up yet");
		parser_.addMandatoryArgument(type);
	}

	protected void addOptionalArgument(ArgType type) throws ParserException {
	
		if (parser_ == null)
			throw new IllegalStateException("parser was not set up yet");
		parser_.addOptionalArgument(type);
	}

	protected CommandLineArguments doParse(String[] args)
			throws ParserException, TException, EDAMUserException,
			EDAMSystemException {
	
		logger_.info("Parsing " + args);
	
		CommandLineArguments cmdline = parser_.parse(args);
	
		logger_.info("Parsing finished: valid: " + cmdline.valid());
	
		if (!cmdline.valid()) {
	
			logger_.info("Invalid cmdline: " + parser_.helpstring());
	
			throw new ParserException(cmdline.getErrorMessages() + "\n"
					+ parser_.helpstring());
		}
	
		setDebug(cmdline.getBoolean(StringConstants.DEBUG));
		setVerbose(cmdline.getBoolean(StringConstants.VERBOSE));
		setQuiet(cmdline.getBoolean(StringConstants.QUIET));
	
		setUsername(cmdline.getString(StringConstants.USERNAME, Preferences
				.retreive(StringConstants.USERNAME)));
		setPassword(cmdline.getString(StringConstants.PASSWORD, Preferences
				.retreive(StringConstants.PASSWORD)));
	
		logger_.info("username: " + getUsername());
		logger_.info("password: " + getPassword());
	
		return cmdline;
	}

	public String getPassword() {
		return password_;
	}

	public String getUsername() {
		return username_;
	}

	public boolean isDebug() {
		return debug_;
	}

	public boolean isQuiet() {
		return quiet_;
	}

	public boolean isVerbose() {
		return verbose_;
	}

	/**
	 * Parse the command line arguments
	 * 
	 * @param args
	 *            command line argument string (parameter to main)
	 * @return true if the arguments are successfully parsed
	 * @throws ParserException
	 *             if the command line can not be parsed
	 * @throws EDAMSystemException
	 * @throws EDAMUserException
	 * @throws TException
	 */
	public CommandLineArguments parse(String[] args) throws ParserException,
			TException, EDAMUserException, EDAMSystemException {
		CommandLineArguments cmdline = doParse(args);
	
		return cmdline;
	}

	public void setDebug(boolean debug) {
		debug_ = debug;
	}

	public void setPassword(String password) {
		password_ = password;
	}

	public void setQuiet(boolean quiet) {
		quiet_ = quiet;
	}

	public void setup(String string) throws ParserException {
	
		parser_ = new Parser(string);
	
		// Logger selector
		parser_.addOptionalArgument(new BooleanArgType("D", StringConstants.DEBUG,
				"Debugging operations"));
		parser_.addOptionalArgument(new BooleanArgType("V", StringConstants.VERBOSE,
				"Verbose operations"));
		parser_.addOptionalArgument(new BooleanArgType("Q", StringConstants.QUIET,
				"Quiet operation"));
	
		parser_.addHiddenArgument(new BooleanArgType("B", StringConstants.BETA,
				"Enable beta features"));
		// rest of the arguments
		parser_.addOptionalArgument(new StringArgType("u", StringConstants.USERNAME,
				"username"));
	
		parser_.addOptionalArgument(new StringArgType("p", StringConstants.PASSWORD,
				"password"));
		
		parser_.addOptionalArgument(new StringArgType("n",StringConstants.NOTEBOOK,"notebook"));
		
		parser_.addOptionalArgument(new StringArgType("f",StringConstants.FILENAME,"filename"));
		
		parser_.addOptionalArgument(new StringArgType("T",StringConstants.NOTE_TITLE,"Note title"));
		
		parser_.addOptionalArgument(new StringArgType("t",StringConstants.TAGS,"tags"));
	
	}

	public void setUsername(String username) {
		username_ = username;
	}

	public void setVerbose(boolean verbose) {
		verbose_ = verbose;
	}

}
